﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Devtm.Generator.Writers;
using System.Xml.Linq;
using Generator.Templates;
using Devtm.Writers;
using System.IO;
using System.Reflection;


namespace Generator.Templates
{
    
    public class ResourceFileGenerator<TContext>: BaseXmlGenerator<Devtm.Generator.Writers.XmlWriter, TContext>, IRun
        where TContext : Devtm.Generator.Contexts.IContext, new()
    {


        public ResourceFileGenerator(TContext context)
            : base(context)
        {


        }


        private bool _initalized = false;
        XElement Root;
        private void Generate()
        {
            
            _initalized = true;

            using (var _Root = this.Writer.AddElement("root"))
            {

                Root = _Root.Item;

                var j = _Root.Item;

                this.Writer.AddComment(Strings.ResourceComment);

                this.Writer.AddElement(XElement.Parse(Strings.ResourceSchema));

                AddResHeader("resmimetype", "text/microsoft-resx");
                AddResHeader("version", "2.0");
                AddResHeader("reader", "System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddResHeader("writer", "System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

            }


        }


        public void AddFile(string key, FileInfo file)
        {
            AddData(key, typeof(System.Resources.ResXFileRef), file.Name, typeof(string));
        }


        public void AddString(string key, string value)
        {

            using (var l = this.Writer.AddElement("data"))
            {

                this.Writer.AddAttribute("name", key);
                this.Writer.AddAttribute("xml:space", "preserve");

                using (var m = this.Writer.AddElement("value"))
                {
                    m.Item.Value = value;
                }

            }

        }


        private void AddData(string key, Type type, string value, Type typeData)
        {
            if (!_initalized)
                Generate();

            string _type = AddAssembly(type);

            using (var l = this.Writer.AddElement("data"))
            {
                this.Writer.AddAttribute("name", key);
                this.Writer.AddAttribute("type", type.AssemblyQualifiedName);

                using (var m = this.Writer.AddElement("value"))
                {
                    m.Item.Value = string.Format("{0};{1}", value, typeData.AssemblyQualifiedName);
                }
            }
        }


        private Dictionary<Assembly, string> _ass = new Dictionary<Assembly, string>();
        private string AddAssembly(Type type)
        {

            Assembly ass = type.Assembly;

            if (_ass.ContainsKey(ass))
                return _ass[ass];

            else
            {

                string alias = ass.GetName().Name;

                using (var k = this.Writer.AddElement("assembly"))
                {
                    this.Writer.AddAttribute("alias", alias);
                    this.Writer.AddAttribute("name", type.Assembly.GetName().FullName);
                }

                return alias;
            
            }
        }


        private void AddResHeader(string type, string value)
        {
            using (var k = this.Writer.AddElement("resheader"))
            {
                this.Writer.AddAttribute("name", type);
                using (var l = this.Writer.AddElement("value"))
                {
                    l.Item.Value = value;
                }
            }
        }
       

    }
}
